#ifndef _UTIL_HPP
#define _UTIL_HPP

#include "Reactor.hpp"

bool SetNonBlock(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    if(fd == -1)
    {
        fprintf(stderr, "fcntl: %s\n", strerror(errno)); 
        return false;
    }
    fcntl(fd, F_SETFL, fl | O_NONBLOCK);

    return true;
}

void SplitSegment(Event* event, std::vector<std::string>* tokens, const std::string& sep)
{
    while(true)
    {
        auto pos = event->_in_buffer.find(sep);
        if(pos == std::string::npos)
        {
            // 没有找到
            break;
        }

        // 找到了
        // 切割字符串
        std::string sub = event->_in_buffer.substr(0, pos);
        // 向tokens插入字符串
        tokens->push_back(sub);
        // 在inbuffer中删除字符串
        event->_in_buffer.erase(0, pos + sep.size());
    }
}

bool IsOp(const char c)
{
    std::unordered_set<char> op_set = { '+', '-', '*', '/', '/' };
    int n = op_set.count(c);
    if(n) return true; 

    return false;
}

int FindOp(const std::string& segment)
{
    int i = 0;
    for(; i < segment.size(); ++i)
    {
        if(IsOp(segment[i]))
        {
            // 找到了
            return i;
        }
        // 没有找到
    }
    return -1;
}

bool Deserialize(std::string& segment, std::string* data1, std::string* data2, std::string* op)
{
    int pos = FindOp(segment);
    if(pos > 0)
    {
        *data1 = segment.substr(0, pos);
        *op = segment[pos];
        *data2 = segment.substr(pos + op->size());
        return true;
    }

    return false;
}

int handler(const std::string& data1, const std::string& data2, const std::string& op)
{
    if(op == std::string("+"))
    {
        return atoi(data1.c_str()) + atoi(data2.c_str());
    }
    
    if(op == std::string("-"))
    {
        return atoi(data1.c_str()) - atoi(data2.c_str());
    }

    if(op == std::string("*"))
    {
        return atoi(data1.c_str()) * atoi(data2.c_str());
    }

    if(op == std::string("/"))
    {
        assert(atoi(data2.c_str()));
        return atoi(data1.c_str()) / atoi(data2.c_str());
    }

    if(op == std::string("%"))
    {
        assert(atoi(data2.c_str()));
        return atoi(data1.c_str()) % atoi(data2.c_str());
    }

    return static_cast<int>(size_t(-1));
}

#endif
